package org.example.netty.test.nio.java;

import lombok.extern.slf4j.Slf4j;

import java.nio.IntBuffer;

/**
 * @author zp
 * @version 1.0
 * @description: 获取一个整型的Buffer实例对象
 * 使用Buffer类的基本步骤
 * 总体来说，使用Java NIO Buffer类的基本步骤如下:
 *
 * （1）使用创建子类实例对象的allocate()方法，创建一个Buffer类的实例对象。
 *
 * （2）调用put( )方法，将数据写入到缓冲区中。
 *
 * （3）写入完成后，在开始读取数据前，调用Buffer.flip()方法，将缓冲区转换为读模式。
 *
 * （4）调用get( )方法，可以从缓冲区中读取数据。
 *
 * （5）读取完成后，调用Buffer.clear()方法或Buffer.compact()方法，将缓冲区转换为写入模式，可以继续写入。
 * @date 2023/2/19 14:22
 */
@Slf4j
public class UseBuffer {
    //一个整型的Buffer静态变量
    static IntBuffer intBuffer = null;
    /**
     * @description:  创建缓冲区
     * @author zp
     * @date: 2023/2/19 14:45
     */
    public static void allocateTest() {
        //创建了一个Intbuffer实例对象
        intBuffer = IntBuffer.allocate(20);
        log.debug("------------after allocate------------------");
        log.debug("position=" + intBuffer.position());
        log.debug("limit=" + intBuffer.limit());
        log.debug("capacity=" + intBuffer.capacity());
    }
    /**
     * @description:  放入缓冲区数据
     * @author zp
     * @date: 2023/2/19 14:46
     */
    public static void putTest() {
        for (int i = 0; i < 5; i++) {
            //写入一个整数到缓冲区
            intBuffer.put(i);
        }

        //输出缓冲区的主要属性值
        log.debug("------------after putTest------------------");
        log.debug("position=" + intBuffer.position());
        log.debug("limit=" + intBuffer.limit());
        log.debug("capacity=" + intBuffer.capacity());
    }
    /**
     * @description:  翻转缓冲区的读写模式
     * @author zp
     * @date: 2023/2/19 14:46
     */
    public static void flipTest() {
        // 翻转缓冲区，从写入模式翻转成读取模式
        intBuffer.flip();
        // 输出缓冲区的主要属性值
        log.info("------------after flip ------------------");
        log.info("position=" + intBuffer.position());
        log.info("limit=" + intBuffer.limit());
        log.info("capacity=" + intBuffer.capacity());
    }
    /**
     * @description:  清除缓冲区数据 重新重置缓冲区
     * @author zp
     * @date: 2023/2/19 14:46
     */
    public static void clearTest() {
        // 清除缓冲区，从读入模式翻转成写取模式
        intBuffer.clear();
        // 输出缓冲区的主要属性值
        log.info("------------after clear ------------------");
        log.info("position=" + intBuffer.position());
        log.info("limit=" + intBuffer.limit());
        log.info("capacity=" + intBuffer.capacity());
    }

    /**
     * @description:  获取缓冲区数据
     * @author zp
     * @date: 2023/2/19 14:47
     */
    public static void getTest() {
        log.info("---------get 2 int --------------");
        //先读2个数据
        for (int i = 0; i < 2; i++) {
            int j = intBuffer.get();
            log.info("j = " + j);
        }
        //输出缓冲区的主要属性值
        log.info("---------after get 2 int --------------");
        log.info("position=" + intBuffer.position());
        log.info("limit=" + intBuffer.limit());
        log.info("capacity=" + intBuffer.capacity());
        //再读3个数据
        for (int i = 0; i < 3; i++) {
            int j = intBuffer.get();
            log.info("j = " + j);
        }
        //输出缓冲区的主要属性值
        log.info("---------after get 3 int ---------------");
        log.info("position=" + intBuffer.position());
        log.info("limit=" + intBuffer.limit());
        log.info("capacity=" + intBuffer.capacity());
    }
    /**
     * @description:  倒带缓冲区数据 方便重新读取
     * @author zp
     * @date: 2023/2/19 14:47
     */
    public static void rewindTest() {
        // 倒带
        intBuffer.rewind();
        // 输出缓冲区的主要属性值
        log.info("------------after rewind ------------------");
        log.info("position=" + intBuffer.position());
        log.info("limit=" + intBuffer.limit());
        log.info("capacity=" + intBuffer.capacity());
    }

    /**
     * @description: 重新读取
     * @author zp
     * @date: 2023/2/19 14:43
     */
    public static void reRead() {
        for (int i = 0; i < 5; i++) {
            if (i == 2) {
                //临时保存，标记一下第3个位置
                intBuffer.mark();
            }
            //读取元素
            int j = intBuffer.get();
            log.info("j = " + j);
            log.info("------------after reRead ------------------");
            log.info("position=" + intBuffer.position());
            log.info("limit=" + intBuffer.limit());
            log.info("capacity=" + intBuffer.capacity());
        }
    }

    public static void afterReset() {
        log.info("------------after reset------------------");
        //把前面保存在mark中的值恢复到position
        intBuffer.reset();
        //输出缓冲区的属性值
        log.info("position=" + intBuffer.position());
        log.info("limit=" + intBuffer.limit());
        log.info("capacity=" + intBuffer.capacity());
        //读取并且输出元素
        for (int i = 2; i <5 ; i++) {
            int j = intBuffer.get();
            log.info("j = " + j);
        }
    }
}
